package org.ehl.core.servlet;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.ehl.core.entity.AnnotationBean;

public class DispatcherServlet extends HttpServlet {

	private static final long serialVersionUID = 5019691419551593460L;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Map<String, AnnotationBean> handlerMapping = (Map<String, AnnotationBean>) request.getServletContext().getAttribute("handlerMapping");
		String servletPath = this.getRequesrtPath(request);
		String methodPath = request.getQueryString().split("&")[0];
		AnnotationBean actionBean = handlerMapping.get(servletPath);

		String methodName = actionBean.getMethodMapping().get(methodPath);
		try {
			Class clazz = Class.forName(actionBean.getActionClass());
			Object action = null;
			try {
				action = clazz.newInstance();
			} catch (InstantiationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			Method[] methods = clazz.getDeclaredMethods();

			for (Method method : methods) {
				if (method.getName().equals(methodName)) {

					// 构建方法参数
					Class<?>[] parameterTypes = method.getParameterTypes();
					Object[] params = new Object[parameterTypes.length];
					if (parameterTypes != null && parameterTypes.length > 0) {
						for (int i = 0; i < parameterTypes.length; i++) {
							Class<?> parameterType = parameterTypes[i];
							if (parameterType == HttpServletRequest.class) {
								params[i] = request;
							} else if (parameterType == HttpServletResponse.class) {
								params[i] = response;
							} else if (parameterType == HttpSession.class) {
								params[i] = request.getSession();
							} else {
								params[i] = getParamObj(request, parameterType);
							}
						}
					}

					// 执行方法
					try {
						Object result = method.invoke(action, params);
						if (result != null) {

							request.getRequestDispatcher(result.toString()).forward(request, response);

						}

					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private Object getParamObj(HttpServletRequest request, Class<?> parameterType) {
		Object result = null;
		try {
			result = parameterType.newInstance();
			Field[] fields = parameterType.getDeclaredFields();
			if (fields != null) {
				for (Field field : fields) {
					if (!Modifier.isFinal(field.getModifiers())) {
						field.setAccessible(true);
						field.set(result, request.getParameter(field.getName()));
						field.setAccessible(false);
					}
				}
			}
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 获取访问的路径
	 * 
	 * @param request
	 * @return
	 */
	private String getRequesrtPath(HttpServletRequest request) {
		System.out.println(request.getServletPath());
		return request.getServletPath().split("\\.")[0];
	}

}
